package com.terrynoya.fight.commands
{
	import com.terrynoya.fight.emuns.ButtonState;
	import com.terrynoya.fight.emuns.Facing;
	import com.terrynoya.fight.emuns.PlayerButton;

	public class InputBuffer
	{
		private var _size:int;
		
		private var _buffer:CircularBuffer;
		
		public function InputBuffer()
		{
			this._buffer = new CircularBuffer(120);
			this._size = this._buffer.size;
		}
		
		public function get size():int
		{
			return _size;
		}

		public function set size(value:int):void
		{
			_size = value;
		}

		public function add(input:int,facing:int):void
		{
			if (facing == Facing.LEFT)
			{
				if (((input & PlayerButton.Left) == PlayerButton.Left) != ((input & PlayerButton.Right) == PlayerButton.Right))
				{
					input ^= PlayerButton.Left;
					input ^= PlayerButton.Right;
				}
			}
			
			if (((input & PlayerButton.Up) == PlayerButton.Up) && ((input & PlayerButton.Down) == PlayerButton.Down))
			{
				input &= ~PlayerButton.Up;
				input &= ~PlayerButton.Down;
			}
			
			if (((input & PlayerButton.Left) == PlayerButton.Left) && ((input & PlayerButton.Right) == PlayerButton.Right))
			{
				input &= ~PlayerButton.Left;
				input &= ~PlayerButton.Right;
			}
			this._buffer.add(input);
			this._size = this._buffer.size;
		}
		
		public function getText():String
		{
			return this._buffer.getText();
		}
		
		public function getState(inputIndex:int,element:CommandElement):int
		{
			var current:int = int(this._buffer.reverseGet(inputIndex));
			var previous:int = (inputIndex != this._size - 1) ? int(this._buffer.reverseGet(inputIndex + 1)) : 0;
			
			var currentState:Boolean = this.getButtonState(current,element);
			var prevState:Boolean = this.getButtonState(previous,element);
			if(currentState)
			{
				return prevState ? ButtonState.Down : ButtonState.Pressed;
			}
			else
			{
				return prevState ? ButtonState.Released : ButtonState.Up;
			}
		}
		
		private function getButtonState(inputElement:int,commandElement:CommandElement):Boolean
		{
			var match1:Boolean = (inputElement & commandElement.matchHash1) == commandElement.matchHash1;
			var match2:Boolean = (inputElement & commandElement.matchHash2) == 0;
			return match1 && match2;
		}
	}
}